package xq;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class ChessBoard extends JPanel implements Runnable {// 棋盘类		
	public static final short REDPLAYER = 1;
	public static final short BLACKPLAYER = 0;
	public Chess[] chess = new Chess[32]; // 所有棋子
	public int[][] Map = new int[9 + 1][10 + 1]; //棋盘的棋子布局
	public Image bufferImage; // 双缓存
	private Chess firstChess2 = null; // 鼠标单击时选定的棋子
	private Chess secondChess2 = null;
	private boolean first = true; // 区分第一次跟第二次选中的棋子
	private int x1, y1, x2, y2;
	private int tempx, tempy;
	private int r; // 棋子半径
	private boolean IsMyTurn = true; // IsMyTurn判断是否该自己走了
	public short LocalPlayer = REDPLAYER; // LocalPlayer记录自己是红方还是黑方
	private String message = ""; // 提示信息
	// 线程消亡的标识位
	private boolean flag = false;
	private int otherport; // 对方端口
	private int receiveport; // 本机接收端口

	public void startJoin(String ip, int otherport, int receiveport) // 开始
	{
		flag = true;
		this.otherport = otherport;
		this.receiveport = receiveport;
		send("join|");
		// 创建一个线程()
		Thread th = new Thread(this);
		// 启动线程
		th.start();
		message = "程序处于等待联机状态！";
	}

	public ChessBoard()// 构造方法
	{
		r = 20;
		cls_map();
		/**
		 * 鼠标事件监听
		 */
		addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (IsMyTurn == false) {
					message = "该对方走棋";
					repaint();
					return;
				}
				int x = e.getX();
				int y = e.getY();
				selectChess(e);
				System.out.println(x);
				repaint();
			}

			private void selectChess(MouseEvent e) {
				int idx, idx2; // 保存第一次和第二次被单击棋子的索引号
				if (first) {
					// 第一次棋子
					firstChess2 = analyse(e.getX(), e.getY());
					x1 = tempx;
					y1 = tempy;
					if (firstChess2 != null) {
						if (firstChess2.player != LocalPlayer) {
							message = "单击成对方棋子了!";
							return;
						}
						first = false;
					}
				} else {
					// 第2次棋子
					secondChess2 = analyse(e.getX(), e.getY());
					x2 = tempx;
					y2 = tempy;
					// 如果是自己的棋子,则换上次选择的棋子
					if (secondChess2 != null) {
						if (secondChess2.player == LocalPlayer) {
							// 取消上次选择的棋子
							firstChess2 = secondChess2;
							x1 = tempx;
							y1 = tempy;
							secondChess2 = null;
							return;
						}
					}
					if (secondChess2 == null) // 目标处没棋子，移动棋子
					{
						if (IsAbleToPut(firstChess2, x2, y2)) {
							// 在map取掉原CurSelect棋子
							idx = Map[x1][y1];
							Map[x1][y1] = -1;
							Map[x2][y2] = idx;
							chess[idx].SetPos(x2, y2);
							// send
							send("move" + "|" + idx + "|" + (10 - x2) + "|"
									+ String.valueOf(11 - y2) + "|");
							// CurSelect = 0;
							first = true;
							repaint();
							SetMyTurn(false); // 该对方了
							// toolStripStatusLabel1.Text = "";
						} else {
							// 错误走棋
							message = "不符合走棋规则";
						}
						return;

					}
					if (secondChess2 != null
							&& IsAbleToPut(firstChess2, x2, y2)) // 可以吃子
					{
						first = true;
						// 在map取掉原CurSelect棋子
						idx = Map[x1][y1];
						idx2 = Map[x2][y2];
						Map[x1][y1] = -1;
						Map[x2][y2] = idx;
						chess[idx].SetPos(x2, y2);
						chess[idx2] = null;
						repaint();
						if (idx2 == 0) // 0---"将"
						{
							message = "红方赢了";
							JOptionPane.showConfirmDialog(null, "红方赢了", "提示",
									JOptionPane.DEFAULT_OPTION);
							// send
							send("move" + "|" + idx + "|" + (10 - x2) + "|"
									+ String.valueOf(11 - y2) + "|");
							send("succ" + "|" + "红方赢了" + "|");
							// btnNew.setEnabled(true); //可以重新开始
							return;
						}
						if (idx2 == 16) // 16--"帅"
						{
							message = "黑方赢了";
							JOptionPane.showConfirmDialog(null, "黑方赢了", "提示",
									JOptionPane.DEFAULT_OPTION);
							send("move" + "|" + idx + "|" + (10 - x2) + "|"
									+ String.valueOf(11 - y2) + "|");
							send("succ" + "|" + "黑方赢了" + "|");
							// btnNew.setEnabled(true); //可以重新开始
							return;
						}
						// send
						send("move" + "|" + idx + "|" + (10 - x2) + "|"
								+ String.valueOf(11 - y2) + "|");
						SetMyTurn(false); // 该对方了
						// toolStripStatusLabel1.Text = "";
					} else // 不能吃子
					{
						message = "不能吃子";
					}
				}
			}
			
		});
	}
	// 解析鼠标之下的棋子对象
	private Chess analyse(int x, int y) {
		tempx = (int) Math.floor((double) x / 40) + 1;
		tempy = (int) Math.floor((double) (y - 20) / 40) + 1;
		System.out.println(x + " , " + y);
		System.out.println(tempx + " , " + tempy);
		// 防止超出范围
		if (tempx > 9 || tempy > 10 || tempx < 0 || tempy < 0) {
			return null;
		} else {
			int idx = Map[tempx][tempy];
			if (idx == -1) {
				return null;
			}
			return chess[idx];
		}
	}

	private boolean IsMyChess(int idx) {
		boolean functionReturnValue = false;
		if (idx >= 0 && idx < 16 && LocalPlayer == BLACKPLAYER) {
			functionReturnValue = true;
		}
		if (idx >= 16 && idx < 32 && LocalPlayer == REDPLAYER) {
			functionReturnValue = true;
		}
		return functionReturnValue;
	}
	// 设置是否该自己走的提示信息
	private void SetMyTurn(boolean bolIsMyTurn) {
		IsMyTurn = bolIsMyTurn;
		if (bolIsMyTurn) {
			message = "请您开始走棋";
		} else {
			message = "对方正在思考...";
		}
		/*
		 * //add 7-1 if(LocalPlayer==REDPLAYER) LocalPlayer=BLACKPLAYER; else
		 * LocalPlayer=REDPLAYER; //add 7-1
		 */}

	public void send(String str)// 发送信息
	{
		// message=str;
		DatagramSocket s = null;
		try {
			s = new DatagramSocket();
			byte[] buffer;
			buffer = new String(str).getBytes();
			InetAddress ia = InetAddress.getLocalHost();// 本机地址
			// 目的主机地址
			// InetAddress ia =
			DatagramPacket dgp = new DatagramPacket(buffer, buffer.length, ia,
					otherport);
			s.send(dgp);
			System.out.println("发送信息:" + str);

		} catch (IOException e) {
			System.out.println(e.toString());
		} finally {
			if (s != null)
				s.close();
		}
	}

	private void cls_map() {
		int i, j;
		for (i = 1; i <= 9; i++) {
			for (j = 1; j <= 10; j++) {
				Map[i][j] = -1;
			}
		}
	}

	public final void NewGame(short player) // 棋子初始布局
	{
		cls_map(); // 清空存储棋子信息数组
		InitChess();//初始棋子布局
		if (player == BLACKPLAYER) {
			ReverseBoard();
		}
		repaint();
	}

	private void InitChess() {
		// 布置黑方棋子
		chess[0] = new Chess(BLACKPLAYER, "将", new Point(5, 1));
		Map[5][1] = 0;
		chess[1] = new Chess(BLACKPLAYER, "士", new Point(4, 1));
		Map[4][1] = 1;
		chess[2] = new Chess(BLACKPLAYER, "士", new Point(6, 1));
		Map[6][1] = 2;
		chess[3] = new Chess(BLACKPLAYER, "象", new Point(3, 1));
		Map[3][1] = 3;
		chess[4] = new Chess(BLACKPLAYER, "象", new Point(7, 1));
		Map[7][1] = 4;
		chess[5] = new Chess(BLACKPLAYER, "马", new Point(2, 1));
		Map[2][1] = 5;
		chess[6] = new Chess(BLACKPLAYER, "马", new Point(8, 1));
		Map[8][1] = 6;

		chess[7] = new Chess(BLACKPLAYER, "车", new Point(1, 1));
		Map[1][1] = 7;
		chess[8] = new Chess(BLACKPLAYER, "车", new Point(9, 1));
		Map[9][1] = 8;

		chess[9] = new Chess(BLACKPLAYER, "炮", new Point(2, 3));
		Map[2][3] = 9;
		chess[10] = new Chess(BLACKPLAYER, "炮", new Point(8, 3));
		Map[8][3] = 10;

		for (int i = 0; i <= 4; i++) {
			chess[11 + i] = new Chess(BLACKPLAYER, "卒", new Point(1 + i * 2, 4));
			Map[1 + i * 2][4] = 11 + i;
		}

		// 布置红方棋子
		chess[16] = new Chess(REDPLAYER, "帅", new Point(5, 10));
		Map[5][10] = 16;
		chess[17] = new Chess(REDPLAYER, "仕", new Point(4, 10));
		Map[4][10] = 17;
		chess[18] = new Chess(REDPLAYER, "仕", new Point(6, 10));
		Map[6][10] = 18;
		chess[19] = new Chess(REDPLAYER, "相", new Point(3, 10));
		Map[3][10] = 19;
		chess[20] = new Chess(REDPLAYER, "相", new Point(7, 10));
		Map[7][10] = 20;
		chess[21] = new Chess(REDPLAYER, "马", new Point(2, 10));
		Map[2][10] = 21;
		chess[22] = new Chess(REDPLAYER, "马", new Point(8, 10));
		Map[8][10] = 22;

		chess[23] = new Chess(REDPLAYER, "车", new Point(1, 10));
		Map[1][10] = 23;
		chess[24] = new Chess(REDPLAYER, "车", new Point(9, 10));
		Map[9][10] = 24;

		chess[25] = new Chess(REDPLAYER, "炮", new Point(2, 8));
		Map[2][8] = 25;
		chess[26] = new Chess(REDPLAYER, "炮", new Point(8, 8));
		Map[8][8] = 26;

		for (int i = 0; i <= 4; i++) {
			chess[27 + i] = new Chess(REDPLAYER, "兵", new Point(1 + i * 2, 7));
			Map[1 + i * 2][7] = 27 + i;
		}
	}

	// 重画场景中所有对象
	public void paint(Graphics g) {
		g.clearRect(0, 0, this.getWidth(), this.getHeight());
		// BufferedImage bi = new BufferedImage(500, 500,
		// BufferedImage.TYPE_INT_RGB);
		// Graphics g2 = bi.createGraphics();
		// g2.setColor(Color.BLACK);
		Image bgImage = Toolkit.getDefaultToolkit().getImage("xq//qipan.jpg");
		// 绘制背景棋盘
		g.drawImage(bgImage, 1, 20, this);

		// 画棋子
		for (int i = 0; i < 32; i++) {
			if (chess[i] != null) {
				chess[i].paint(g, this);
				// System.out.print(chess[i].typeName);
			}
		}
		if (firstChess2 != null) {
			firstChess2.DrawSelectedChess(g);
		}
		if (secondChess2 != null) {
			secondChess2.DrawSelectedChess(g);
		}
		// 缓存输出
		// g.drawImage(bufferImage, 0, 0, 360, 400,this);
		// g.drawImage(bgImage, 0, 0, this);
		g.drawString(message, 0, 450);
	}

	private void ReverseBoard() // 翻转棋子
	{
		int x, y, c;
		// 对调(x,y)与(10-x,11-y)处棋子
		for (int i = 0; i < 32; i++) {
			if (chess[i] != null) {
				chess[i].ReversePos();
			}
		}
		// 对调Map记录的棋子索引号
		for (x = 1; x <= 9; x++) {
			for (y = 1; y <= 5; y++) {
				if (Map[x][y] != -1) {
					c = Map[10 - x][11 - y];
					Map[10 - x][11 - y] = Map[x][y];
					Map[x][y] = c;
				}
			}
		}

	}

	// IsAbleToPut(firstchess, x, y)实现判断是否能走棋返回逻辑值，这代码最复杂。
	public final boolean IsAbleToPut(Chess firstchess, int x, int y) {
		int i, j, c;
		int oldx, oldy; // 在棋盘原坐标
		oldx = firstchess.pos.x;
		oldy = firstchess.pos.y;
		String qi_name = firstchess.typeName;
		if (qi_name.equals("将") || qi_name.equals("帅")) {
			if ((x - oldx) * (y - oldy) != 0) {
				return false;
			}
			if (Math.abs(x - oldx) > 1 || Math.abs(y - oldy) > 1) {
				return false;
			}
			if (x < 4 || x > 6 || (y > 3 && y < 8)) {
				return false;
			}
			return true;
		}
		if (qi_name.equals("士") || qi_name.equals("仕")) {
			if ((x - oldx) * (y - oldy) == 0) {
				return false;
			}
			if (Math.abs(x - oldx) > 1 || Math.abs(y - oldy) > 1) {
				return false;
			}
			if (x < 4 || x > 6 || (y > 3 && y < 8)) {
				return false;
			}
			return true;
		}

		if (qi_name.equals("象") || qi_name.equals("相")) {
			if ((x - oldx) * (y - oldy) == 0) {
				return false;
			}
			if (Math.abs(x - oldx) != 2 || Math.abs(y - oldy) != 2) {
				return false;
			}
			if (y < 6) {
				return false;
			}
			i = 0; // i,j必须有初始值
			j = 0;
			if (x - oldx == 2) {
				i = x - 1;
			}
			if (x - oldx == -2) {
				i = x + 1;
			}
			if (y - oldy == 2) {
				j = y - 1;
			}
			if (y - oldy == -2) {
				j = y + 1;
			}
			if (Map[i][j] != -1) {
				return false;
			}
			return true;
		}
		if (qi_name.equals("马") || qi_name.equals("马")) {
			if (Math.abs(x - oldx) * Math.abs(y - oldy) != 2) {
				return false;
			}
			if (x - oldx == 2) {
				if (Map[x - 1][oldy] != -1) {
					return false;
				}
			}
			if (x - oldx == -2) {
				if (Map[x + 1][oldy] != -1) {
					return false;
				}
			}
			if (y - oldy == 2) {
				if (Map[oldx][y - 1] != -1) {
					return false;
				}
			}
			if (y - oldy == -2) {
				if (Map[oldx][y + 1] != -1) {
					return false;
				}
			}
			return true;
		}
		if (qi_name.equals("车") || qi_name.equals("车")) {
			// 判断是否直线
			if ((x - oldx) * (y - oldy) != 0) {
				return false;
			}
			// 判断是否隔有棋子
			if (x != oldx) {
				if (oldx > x) {
					int t = x;
					x = oldx;
					oldx = t;
				}
				for (i = oldx; i <= x; i += 1) {
					if (i != x && i != oldx) {
						if (Map[i][y] != -1) {
							return false;
						}
					}
				}
			}
			if (y != oldy) {
				if (oldy > y) {
					int t = y;
					y = oldy;
					oldy = t;
				}
				for (j = oldy; j <= y; j += 1) {
					if (j != y && j != oldy) {
						if (Map[x][j] != -1) {
							return false;
						}
					}
				}
			}
			return true;
		}
		if (qi_name.equals("炮") || qi_name.equals("炮")) {
			boolean swapflagx = false;
			boolean swapflagy = false;
			if ((x - oldx) * (y - oldy) != 0) {
				return false;
			}
			c = 0;
			if (x != oldx) {
				if (oldx > x) {
					int t = x;
					x = oldx;
					oldx = t;
					swapflagx = true;
				}
				for (i = oldx; i <= x; i += 1) {
					if (i != x && i != oldx) {
						if (Map[i][y] != -1) {
							c = c + 1;
						}
					}
				}
			}
			if (y != oldy) {
				if (oldy > y) {
					int t = y;
					y = oldy;
					oldy = t;
					swapflagy = true;
				}
				for (j = oldy; j <= y; j += 1) {
					if (j != y && j != oldy) {
						if (Map[x][j] != -1) {
							c = c + 1;
						}
					}
				}
			}
			if (c > 1) // 与目标处间隔1个以上棋子
			{
				return false;
			}
			if (c == 0) // 与目标处无间隔棋子
			{
				if (swapflagx == true) {
					int t = x;
					x = oldx;
					oldx = t;
				}
				if (swapflagy == true) {
					int t = y;
					y = oldy;
					oldy = t;
				}
				if (Map[x][y] != -1) {
					return false;
				}
			}
			if (c == 1) // 与目标处间隔1个棋子
			{
				if (swapflagx == true) {
					int t = x;
					x = oldx;
					oldx = t;
				}
				if (swapflagy == true) {
					int t = y;
					y = oldy;
					oldy = t;
				}
				if (Map[x][y] == -1) // 如果目标处无棋子，则不能走此步
				{
					return false;
				}
			}
			return true;
		}
		if (qi_name.equals("卒") || qi_name.equals("兵")) {
			if ((x - oldx) * (y - oldy) != 0) {
				return false;
			}
			if (Math.abs(x - oldx) > 1 || Math.abs(y - oldy) > 1) {
				return false;
			}
			if (y >= 6 && (x - oldx) != 0) {
				return false;
			}
			if (y - oldy > 0) {
				return false;
			}
			return true;
		}
		return false;
	}

	// 线程执行的内容
	public void run() {
		try {
			// 指定接收端口
			DatagramSocket s = new DatagramSocket(receiveport);
			byte[] data = new byte[100];
			DatagramPacket dgp = new DatagramPacket(data, data.length);
			// 进入一个无限循环中来接收数据包
			while (flag == true) {
				s.receive(dgp); // 接收数据包
				String strData = new String(data);
				String[] a = new String[6];
				a = strData.split("\\|");
				System.out.println("接收数据信息:" + strData + "分割命令：" + a[0]);
				if (a[0].equals("join")) {
					LocalPlayer = BLACKPLAYER;
					// 显示棋子
					NewGame(LocalPlayer);
					if (LocalPlayer == REDPLAYER) {
						SetMyTurn(true); // 能走棋
					} else {
						SetMyTurn(false);
					}
					// 发送联机成功信息
					send("conn|");
				} else if (a[0].equals("conn")) // 联机成功信息
				{
					LocalPlayer = REDPLAYER;
					// 显示棋子
					NewGame(LocalPlayer);
					if (LocalPlayer == REDPLAYER) {
						SetMyTurn(true); // 能走棋
					} else {
						SetMyTurn(false);
					}
				} else if (a[0].equals("succ")) {
					// 获取传送信息到本地端口号的远程计算机IP地址
					if (a[1].equals("黑方赢了")) {
						JOptionPane.showConfirmDialog(null, "黑方赢了,你可以重新开始了！",
								"你输了", JOptionPane.DEFAULT_OPTION);
					}
					if (a[1].equals("红方赢了")) {
						JOptionPane.showConfirmDialog(null, "红方赢了,你可以重新开始了！",
								"你输了", JOptionPane.DEFAULT_OPTION);
					}
					message = "你可以重新开局！";
					// btnNew.setEnabled(true);
				} else if (a[0].equals("move")) {
					// 对方的走棋信息,move|棋子索引号|X|Y
					int idx = Short.parseShort(a[1]);
					x2 = Short.parseShort(a[2]);
					y2 = Short.parseShort(a[3]);
					String z = a[4]; // 对方上步走棋的棋谱信息
					message = x2 + ":" + y2;
					Chess c = chess[idx];
					x1 = c.pos.x; // （x1,y1)是移动棋子原处棋盘坐标
					y1 = c.pos.y;

					// 修改棋子位置,显示对方走棋
					idx = Map[x1][y1];
					int idx2 = Map[x2][y2];
					Map[x1][y1] = -1;
					Map[x2][y2] = idx;
					chess[idx].SetPos(x2, y2);
					if (idx2 != -1) {
						chess[idx2] = null;
					}
					repaint();
					IsMyTurn = true;
					// SetMyTurn(true);
				} else if (a[0].equals("quit")) {
					JOptionPane.showConfirmDialog(null, "对方退出了，游戏结束！", "提示",
							JOptionPane.DEFAULT_OPTION);
					message = "对方退出了，游戏结束！";
					flag = false;
				} else if (a[0].equals("lose")) {
					JOptionPane.showConfirmDialog(null, "恭喜你，对方认输了！", "你赢了",
							JOptionPane.DEFAULT_OPTION);
					SetMyTurn(false);
					// btnNew.setEnabled(true);
				}
				System.out.println(new String(data));
				// s.send (dgp);
			}
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
// 棋盘类
